package com.edward.migration.service.impl;

import com.edward.migration.mapper.MigrationDatabaseInfoMapper;
import com.edward.migration.model.MigrationDatabaseInfo;
import com.edward.migration.model.MigrationTableInfo;
import com.edward.migration.service.IMigrationDatabaseInfoService;
import com.edward.migration.service.IMigrationTableInfoService;
import com.edward.migration.utils.Sm4Util;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.ApplicationArguments;
import org.springframework.boot.ApplicationRunner;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Component;
import org.springframework.transaction.TransactionStatus;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.support.TransactionTemplate;

import javax.sql.DataSource;
import java.sql.Connection;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;


@Component
@Slf4j
public class MigrationDatabaseInfoServiceImpl extends BaseServiceImpl<MigrationDatabaseInfoMapper, MigrationDatabaseInfo> implements IMigrationDatabaseInfoService {

    @Autowired
    private IMigrationTableInfoService migrationTableInfoService;

    @Value("${sm4.key}")
    private String sm4Key;

    @Override
    public Object getInfo() throws Exception {
        List<Map<String, Object>> maps = new ArrayList<>();
        List<MigrationDatabaseInfo> migrationDatabaseInfos = mapper.selectAll();
        int i = 0;
        for (MigrationDatabaseInfo databaseInfo : migrationDatabaseInfos) {
            JdbcTemplate jdbcTemplate = DbConnect.getJdbcTemplate(databaseInfo);
            MigrationTableInfo tableInfo = new MigrationTableInfo();
            tableInfo.setDataCode(databaseInfo.getDataCode());
            List<MigrationTableInfo> migrationTableInfos = migrationTableInfoService.selectByCondition(tableInfo);
            Connection connection = jdbcTemplate.getDataSource().getConnection();
            System.out.println(connection);
            try {
                connection.setAutoCommit(false);
                System.out.println(connection);
                for (MigrationTableInfo migrationTableInfo : migrationTableInfos) {
                    String sql = "select id ," + migrationTableInfo.getTableColumn() + " from " + migrationTableInfo.getTableName();
                    log.info("执行的sql是：{}", sql);
                    maps = jdbcTemplate.queryForList(sql);
                    for (Map<String, Object> map : maps) {
                        i++;
                        StringBuilder update = new StringBuilder("update ").append(migrationTableInfo.getTableName()).append(" set ");
                        Object id = map.remove("id");
                        boolean allParamIsNull = true;
                        for (Map.Entry<String, Object> entry : map.entrySet()) {
                            Object value = entry.getValue();
                            //参数全为空 不更新
                            allParamIsNull = allParamIsNull && (value == null);
                            if (value == null) {
                                continue;
                            }
                            value = Sm4Util.encryptEcb(sm4Key, value.toString());
                            update.append(entry.getKey()).append(" = '").append(value).append("', ");
                        }
                        if(!allParamIsNull){
                            String updateSQL = update.substring(0, update.lastIndexOf(",")) + " where id = " + id + ";";
                            log.info("update sql is {}", updateSQL);
                            if (i >10){
//                                int c = 1/0;
                            }
                            jdbcTemplate.update(updateSQL);
                        }
                    }
                }
                connection.commit();
            } catch (Exception e) {
                e.printStackTrace();
                connection.rollback();
            } finally {
                if(connection != null){
                    connection.setAutoCommit(true);
                }
            }

        }
        return maps;
    }

    public int countNums(JdbcTemplate jdbcTemplate, String table) {
        String countSql = "select count(1) from " + table;
        return jdbcTemplate.queryForObject(countSql, Integer.class);
    }


    @Override
    @Transactional(rollbackFor = Exception.class)
    public Object getInfoTransaction(){
        List<MigrationDatabaseInfo> migrationDatabaseInfos = mapper.selectAll();
        for (MigrationDatabaseInfo databaseInfo : migrationDatabaseInfos) {
            DataSource datasource = DbConnect.getDatasource(databaseInfo);
            TransactionTemplate transactionTemplate = DbConnect.getTransactionTemplate(datasource);
            JdbcTemplate jdbcTemplate = DbConnect.getJdbcTemplate(datasource);
            MigrationTableInfo tableInfo = new MigrationTableInfo();
            tableInfo.setDataCode(databaseInfo.getDataCode());
            List<MigrationTableInfo> migrationTableInfos = migrationTableInfoService.selectByCondition(tableInfo);
            transactionTemplate.execute( (TransactionStatus transactionStatus) ->{
                Object savepoint = transactionStatus.createSavepoint();
                try {
                    for (MigrationTableInfo migrationTableInfo : migrationTableInfos) {
                        String sql = "select id ," + migrationTableInfo.getTableColumn() + " from " + migrationTableInfo.getTableName();
                        log.info("执行的sql是：{}", sql);
                        List<Map<String, Object>> maps = jdbcTemplate.queryForList(sql);
                        for (Map<String, Object> map : maps) {
                            StringBuilder update = new StringBuilder("update ").append(migrationTableInfo.getTableName()).append(" set ");
                            Object id = map.remove("id");
                            boolean allParamIsNull = true;
                            for (Map.Entry<String, Object> entry : map.entrySet()) {
                                Object value = entry.getValue();
                                //参数全为空 不更新
                                allParamIsNull = allParamIsNull && (value == null);
                                if (value == null) {
                                    continue;
                                }
                                value = Sm4Util.encryptEcb(sm4Key, value.toString());
                                update.append(entry.getKey()).append(" = '").append(value).append("', ");
                            }
                            if (!allParamIsNull) {
                                String updateSQL = update.substring(0, update.lastIndexOf(",")) + " where id = " + id + ";";
                                log.info("update sql is {}", updateSQL);
                                jdbcTemplate.update(updateSQL);
                            }
                        }
                    }
                }catch (Exception e){
                    log.error("异常信息是: {}", e.getMessage());
                    transactionStatus.setRollbackOnly();
                    throw new RuntimeException(e);
                }
                return null;
            });
        }
        return "success";
    }

    @Override
    public Object decode() {
        return sm4(false);
    }

    /**
     * true是加密 false解密
     * @param flag
     * @return
     */
    private Object sm4(Boolean flag){
        List<MigrationDatabaseInfo> migrationDatabaseInfos = mapper.selectAll();
        for (MigrationDatabaseInfo databaseInfo : migrationDatabaseInfos) {
            DataSource datasource = DbConnect.getDatasource(databaseInfo);
            TransactionTemplate transactionTemplate = DbConnect.getTransactionTemplate(datasource);
            JdbcTemplate jdbcTemplate = DbConnect.getJdbcTemplate(datasource);
            MigrationTableInfo tableInfo = new MigrationTableInfo();
            tableInfo.setDataCode(databaseInfo.getDataCode());
            List<MigrationTableInfo> migrationTableInfos = migrationTableInfoService.selectByCondition(tableInfo);
            transactionTemplate.execute( (TransactionStatus transactionStatus) ->{
                Object savepoint = transactionStatus.createSavepoint();
                try {
                    for (MigrationTableInfo migrationTableInfo : migrationTableInfos) {
                        String sql = "select id ," + migrationTableInfo.getTableColumn() + " from " + migrationTableInfo.getTableName();
                        log.info("执行的sql是：{}", sql);
                        List<Map<String, Object>> maps = jdbcTemplate.queryForList(sql);
                        for (Map<String, Object> map : maps) {
                            StringBuilder update = new StringBuilder("update ").append(migrationTableInfo.getTableName()).append(" set ");
                            Object id = map.remove("id");
                            boolean allParamIsNull = true;
                            for (Map.Entry<String, Object> entry : map.entrySet()) {
                                Object value = entry.getValue();
                                //参数全为空 不更新
                                allParamIsNull = allParamIsNull && (value == null);
                                if (value == null) {
                                    continue;
                                }
                                if(flag){
                                    value = Sm4Util.encryptEcb(sm4Key, value.toString());
                                }else {
                                    value = Sm4Util.decryptEcb(sm4Key,value.toString());
                                }
                                update.append(entry.getKey()).append(" = '").append(value).append("', ");
                            }
                            if (!allParamIsNull) {
                                String updateSQL = update.substring(0, update.lastIndexOf(",")) + " where id = " + id + ";";
                                log.info("update sql is {}", updateSQL);
                                jdbcTemplate.update(updateSQL);
                            }
                        }
                    }
                }catch (Exception e){
                    log.error("异常信息是: {}", e.getMessage());
                    transactionStatus.setRollbackOnly();
                    throw new RuntimeException(e);
                }
                return null;
            });
        }
        return "success";
    }
//
//    @Override
//    public void run(ApplicationArguments args) throws Exception {
//        log.info("=======================【risk-migrant-data】 Start =====================");
//        this.getInfoTransaction();
//        log.info("=======================【risk-migrant-data】 end Success=====================");
//    }
}
